package com.atguigu.tingshu.account.service.impl;

import com.atguigu.tingshu.account.mapper.RechargeInfoMapper;
import com.atguigu.tingshu.account.mapper.UserAccountDetailMapper;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.account.RechargeInfo;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.model.account.UserAccountDetail;
import com.atguigu.tingshu.vo.account.AccountDeductVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

	@Autowired
	private UserAccountMapper userAccountMapper;

    @Autowired
    private UserAccountDetailMapper userAccountDetailMapper;

    @Autowired
    private RechargeInfoMapper rechargeInfoMapper;
    /**
     * 保存账户信息
     *
     * @param mqData
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUserAccount(Map<String, Object> mqData) {
        //1.保存用户账户记录
        //1.1 从MQ对象中获取业务数据
        Long userId = (Long) mqData.get("userId");
        BigDecimal amount = (BigDecimal) mqData.get("amount");
        UserAccount userAccount = new UserAccount();
        //1.2 构建账户对象
        userAccount.setUserId(userId);
        userAccount.setTotalAmount(amount);
        userAccount.setLockAmount(new BigDecimal("0.00"));
        userAccount.setAvailableAmount(amount);
        userAccount.setTotalIncomeAmount(amount);
        userAccount.setTotalPayAmount(new BigDecimal("0.00"));
        //1.3 保存账户记录
        userAccountMapper.insert(userAccount);
        //2.如果有赠送金额，新增账户变动日志
        String title = (String)mqData.get("title");
        String orderNo = (String)mqData.get("orderNo");
        this.saveUserAccountDetail(userId, title, SystemConstant.ACCOUNT_TRADE_TYPE_DEPOSIT, amount, orderNo);

    }

    /**
     * 保存账户日志明细
     *
     * @param userId    用户ID
     * @param title     交易内容
     * @param tradeType 交易类型
     * @param amount    金额
     * @param orderNo   订单编号
     */
    @Override
    public void saveUserAccountDetail(Long userId, String title, String tradeType, BigDecimal amount, String orderNo) {
        UserAccountDetail userAccountDetail = new UserAccountDetail();
        userAccountDetail.setUserId(userId);
        userAccountDetail.setTitle(title);
        userAccountDetail.setTradeType(tradeType);
        userAccountDetail.setAmount(amount);
        userAccountDetail.setOrderNo(orderNo);
        userAccountDetailMapper.insert(userAccountDetail);
    }

    /**
     * 查询当前用户账户可用余额
     *
     * @param userId
     * @return
     */
    @Override
    public BigDecimal getAvailableAmount(Long userId) {
        LambdaQueryWrapper<UserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserAccount::getUserId, userId);
        queryWrapper.select(UserAccount::getAvailableAmount);
        UserAccount userAccount = userAccountMapper.selectOne(queryWrapper);
        if (userAccount != null) {
            return userAccount.getAvailableAmount();
        }
        return new BigDecimal("0.00");
    }

    /**
     * 扣减账户余额，新增账户变动日志
     *
     * @param accountDeductVo
     * @return
     */
    @Override
    public void checkAndDeduct(AccountDeductVo accountDeductVo) {
        //1.扣减账户余额
        LambdaUpdateWrapper<UserAccount> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.setSql("total_amount = total_amount - " + accountDeductVo.getAmount());
        updateWrapper.setSql("available_amount = available_amount - " + accountDeductVo.getAmount());
        updateWrapper.setSql("total_pay_amount = total_pay_amount + " + accountDeductVo.getAmount());
        updateWrapper.eq(UserAccount::getUserId, accountDeductVo.getUserId());
        updateWrapper.ge(UserAccount::getAvailableAmount, accountDeductVo.getAmount());
        int count = userAccountMapper.update(null, updateWrapper);
        if (count == 0) {
            //抛出异常就会全局异常处理，经过异常处理后给调用方响应Result 业务状态码code不是200
            throw new GuiguException(ResultCodeEnum.ACCOUNT_LESS);
        }
        //2.新增账户变动日志
        this.saveUserAccountDetail(accountDeductVo.getUserId(), accountDeductVo.getContent(), SystemConstant.ACCOUNT_TRADE_TYPE_MINUS, accountDeductVo.getAmount(), accountDeductVo.getOrderNo());
    }

    /**
     * 用户支付成功后，进行余额充值业务
     *
     * @param orderNo 充值订编号
     * @return
     */
    @Override
    public void rechargePaySuccess(String orderNo) {
        //1. 根据充值订单编号查询充值订单信息
        LambdaQueryWrapper<RechargeInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RechargeInfo::getOrderNo, orderNo);
        RechargeInfo rechargeInfo = rechargeInfoMapper.selectOne(queryWrapper);
        if (rechargeInfo != null) {
            rechargeInfo.setRechargeStatus(SystemConstant.ORDER_STATUS_PAID);
            rechargeInfoMapper.updateById(rechargeInfo);
            //2. 账户余额充值
            LambdaUpdateWrapper<UserAccount> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.setSql("total_amount = total_amount + " + rechargeInfo.getRechargeAmount());
            updateWrapper.setSql("available_amount = available_amount + " + rechargeInfo.getRechargeAmount());
            updateWrapper.setSql("total_income_amount = total_income_amount + " + rechargeInfo.getRechargeAmount());
            updateWrapper.eq(UserAccount::getUserId, rechargeInfo.getUserId());
            userAccountMapper.update(null, updateWrapper);
            //3. 新增账户变动日志
            this.saveUserAccountDetail(rechargeInfo.getUserId(), "充值"+rechargeInfo.getRechargeAmount()+"成功", SystemConstant.ACCOUNT_TRADE_TYPE_DEPOSIT, rechargeInfo.getRechargeAmount(), orderNo);
        }
    }

    @Override
    public void getUserAccountDetailPage(Page<UserAccountDetail> pageInfo, String tradeType, Long userId) {
        LambdaQueryWrapper<UserAccountDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserAccountDetail::getUserId, userId);
        queryWrapper.eq(UserAccountDetail::getTradeType, tradeType);
        userAccountDetailMapper.selectPage(pageInfo, queryWrapper);
    }


}
